#include "SocketClient.h"

#define RETRIES 10

/*
 * Client constructor, sets up socket info and connects to the server
 */
SocketClient::SocketClient(const std::string& host, socketType type, int port) : Socket(0,type)
{
    serverPort = port;
    hostInfo = gethostbyname(host.c_str());
    if(hostInfo==NULL) {
        fprintf(stderr, "Unable to obtain host information for %s\n", host.c_str());
    }

    serverAddr.sin_family = hostInfo->h_addrtype;
    serverAddr.sin_port = htons(serverPort);
    memcpy((char *) &serverAddr.sin_addr.s_addr, hostInfo->h_addr_list[0],
        hostInfo->h_length);
    memset(&(serverAddr.sin_zero), 0, 8);

    if(type==tcp) {
        printf("Connecting to server at %s:%i\n", host.c_str(), port);
        if(connect(s, (sockaddr *) &serverAddr, sizeof(serverAddr)) < 0) {
            connected = false;
            fprintf(stderr, "Cannot connect to server");
        }else{
            connected = true;
            printf("Connected to server\n");
        }
    }
}

/*
 * Destructor
 */
SocketClient::~SocketClient() {}

/*
 * Assignment operator
 */
SocketClient& SocketClient::operator=(SocketClient&)
{
    return *this;
}

/*
 * Return connected status
 */ 
bool SocketClient::isConnected()
{
    if(type==udp) return true;
    return connected;
}

/*
 * Disconnect with the server
 */
void SocketClient::serverDisconnected()
{
    int retries = RETRIES;
    connected = false;
    printf("Disconnected with server, trying to reconnect. %i retries\n", retries);
    if(type==tcp) {
        while(retries > 0) {
            if(connect(s, (sockaddr *) &serverAddr, sizeof(serverAddr)) == 0) {
                printf("Connected to server\n");
                connected = true;
                break;
            }
            printf("\r%i retries left", retries);
            retries--;
            // should use the wait function in utilities, but compiling issues
            #ifdef WIN32
                Sleep(10000);
            #else
                sleep(10);
            #endif
        }
    }
}

/*
 * Handle a receieve error
 */
void SocketClient::receiveError(int r, Socket* socket)
{
    int errno;
    if(errno!=0) {
         perror("recv");
         printf("Error reading from socket\n");
    }
    serverDisconnected();
}

/*
 * Send a string of text over the socket
 *
void SocketClient::sendString(char *str)
{
    char msg[MAXMSG];
    itoa((int)strlen(str), msg, 10);
    int l = (int)(strlen(msg) + strlen(str) + 1);
    strcat(msg, " ");
    strcat(msg, str);
    send(s, msg, l, 0);
}*/

/*
 * Receive a string from socket character by character
 *
char* SocketClient::receiveString()
{
    int errno;
    int r = recv(s, buf, MAXMSG, 0);
    if(r<=0) receiveError(r);
    buf[r] = '\0';
    return buf;
}*/

